#include "src/net/EventLoop.h"
#include "src/net/TcpServer.h"

#include <iostream>
#include <string>

using namespace sola;
using namespace sola::net;

// 简单的HTTP上下文，用于存储解析状态
struct HttpContext {
    size_t contentLength   = 0;
    bool   headersComplete = false;
};

// 当新连接建立时调用
void onConnection(const TcpConnectionPtr& conn) {
    if (conn->connected()) {
        // 为每个新连接关联一个HttpContext
        conn->setContext(HttpContext());
        std::cout << "New connection from " << conn->peerAddress().toIpPort() << std::endl;
    } else {
        std::cout << "Connection from " << conn->peerAddress().toIpPort() << " is down." << std::endl;
    }
}

// 当收到消息时调用
void onMessage(const TcpConnectionPtr& conn, Buffer* buf, Timestamp time) {
    HttpContext* context = boost::any_cast<HttpContext>(conn->getMutableContext());

    // 状态机：解析HTTP请求
    // 1. 解析请求头
    if (!context->headersComplete) {
        const char* crlf_crlf = buf->findCRLF();
        if (crlf_crlf && crlf_crlf[0] == '\r' && crlf_crlf[1] == '\n') {
            crlf_crlf = buf->findCRLF(crlf_crlf + 2);
        }

        if (crlf_crlf == nullptr) {
            crlf_crlf = buf->findCRLF();
            if (crlf_crlf && crlf_crlf[0] == '\r' && crlf_crlf[1] == '\n') {
                if (buf->findCRLF(crlf_crlf + 2) == crlf_crlf + 2) {
                    crlf_crlf = crlf_crlf + 2;
                }
            }
        }

        if (crlf_crlf) {
            context->headersComplete = true;
            std::string_view headers(buf->peek(), crlf_crlf - buf->peek());

            // 简单查找Content-Length
            const char* cl_header_start = "Content-Length: ";
            auto        pos             = headers.find(cl_header_start);
            if (pos != std::string_view::npos) {
                size_t start = pos + strlen(cl_header_start);
                size_t end   = headers.find("\r\n", start);
                if (end != std::string_view::npos) {
                    try {
                        context->contentLength = std::stoul(std::string(headers.substr(start, end - start)));
                    } catch (...) {
                        // 解析失败，关闭连接
                        conn->forceClose();
                        return;
                    }
                }
            }

            // 消耗掉请求头和两个\r\n
            buf->retrieveUntil(crlf_crlf + 4);
        } else {
            // 请求头不完整，等待更多数据
            return;
        }
    }

    // 2. 处理请求体
    if (context->headersComplete) {
        if (buf->readableBytes() >= context->contentLength) {
            // 请求体已完整接收
            std::string body = buf->retrieveAsString(context->contentLength);

            // 构造HTTP响应
            std::string response;
            response.append("HTTP/1.1 200 OK\r\n");
            response.append("Content-Type: text/plain\r\n");
            response.append("Content-Length: " + std::to_string(body.size()) + "\r\n");
            response.append("Connection: keep-alive\r\n");
            response.append("\r\n");
            response.append(body);

            conn->send(response);

            // 重置上下文，准备处理同一个连接上的下一个请求 (HTTP keep-alive)
            context->headersComplete = false;
            context->contentLength   = 0;
        }
        // 如果请求体不完整，则继续等待
    }
}

int main(int argc, char* argv[]) {
    if (argc < 2) {
        std::cerr << "Usage: " << argv[0] << " <num_threads>" << std::endl;
        return 1;
    }

    int numThreads = atoi(argv[1]);
    std::cout << "Starting server with " << numThreads << " threads." << std::endl;

    EventLoop   loop;
    InetAddress listenAddr(8888);
    TcpServer   server(&loop, listenAddr, "HttpEchoServer");
    std::cout << "Server listening on " << listenAddr.toIpPort() << std::endl;

    server.setConnectionCallback(onConnection);
    server.setMessageCallback(onMessage);
    server.setThreadNum(numThreads);

    server.start();
    std::cout << "Server started, waiting for connections..." << std::endl;
    loop.loop();

    return 0;
}